package top.jiangqiang.qianyi.common.crypto;

import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.crypto.asymmetric.KeyType;
import org.dromara.hutool.crypto.asymmetric.RSA;
import org.dromara.hutool.crypto.symmetric.AES;
import org.springframework.stereotype.Service;
import top.jiangqiang.qianyi.common.constants.http.Error500Status;
import top.jiangqiang.qianyi.common.exception.Error500Exception;
import top.jiangqiang.qianyi.common.properties.CryptoProperties;

/**
 * 封装了常见加密算法
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CryptoService {

    private final CryptoProperties cryptoProperties;
    @Delegate
    private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    private AES getAes() {
        CryptoProperties.AESConfig aesConfig = cryptoProperties.getAes();
        if (aesConfig == null) {
            throw new Error500Exception(Error500Status.INTERNAL_PLEASE_CHECK_THE_AES_CONFIG);
        }
        if (StrUtil.hasBlank(aesConfig.getAesPassword())) {
            throw new Error500Exception(Error500Status.INTERNAL_PLEASE_CHECK_THE_AES_CONFIG);
        }
        return new AES(aesConfig.getMode(), aesConfig.getPadding(), Base64.decode(aesConfig.getAesPassword()), Base64.decode(aesConfig.getIv()));
    }

    private RSA getRsa() {
        CryptoProperties.RSAConfig rsaConfig = cryptoProperties.getRsa();
        if (rsaConfig == null) {
            throw new Error500Exception(Error500Status.INTERNAL_PLEASE_CHECK_THE_RSA_CONFIG);
        }
        if (StrUtil.hasBlank(rsaConfig.getPrivateKey(), rsaConfig.getPublicKey())) {
            throw new Error500Exception(Error500Status.INTERNAL_PLEASE_CHECK_THE_RSA_CONFIG);
        }
        return new RSA(rsaConfig.getPrivateKey(), rsaConfig.getPublicKey());
    }

    /**
     * aes加密为十六进制字符串
     *
     * @param data 明文
     * @return
     */
    public String aesEncrypt(String data) {
        if (data == null) {
            return null;
        } else {
            return getAes().encryptHex(data);
        }
    }

    /**
     * aes解密
     *
     * @param hexStr 十六进制密文
     * @return
     */
    public String aesDecrypt(String hexStr) {
        if (hexStr == null) {
            return null;
        } else {
            return getAes().decryptStr(hexStr);
        }
    }

    /**
     * rsa加密为十六进制字符串
     *
     * @param data 明文
     * @return
     */
    public String rsaEncrypt(String data) {
        return rsaEncrypt(data, KeyType.PrivateKey);
    }

    /**
     * rsa解密
     *
     * @param hexStr 十六进制密文
     * @return
     */
    public String rsaDecrypt(String hexStr) {
        return rsaDecrypt(hexStr, KeyType.PrivateKey);
    }

    /**
     * rsa加密为十六进制字符串
     *
     * @param data    明文
     * @param keyType 私钥或公钥
     * @return
     */
    public String rsaEncrypt(String data, final KeyType keyType) {
        if (data == null) {
            return null;
        } else {
            return getRsa().encryptHex(data, keyType);
        }
    }

    /**
     * rsa解密
     *
     * @param hexStr  十六进制密文
     * @param keyType 私钥或公钥
     * @return
     */
    public String rsaDecrypt(String hexStr, final KeyType keyType) {
        if (hexStr == null) {
            return null;
        } else {
            return getRsa().decryptStr(hexStr, keyType);
        }
    }
}
